package com.yunquan.ohana.ui.home

import android.app.Application
import androidx.databinding.ObservableField
import androidx.lifecycle.LifecycleOwner
import com.google.gson.Gson
import com.yunquan.ohana.R
import com.yunquan.ohana.base.binding.command.BindingAction
import com.yunquan.ohana.base.binding.command.BindingCommand
import com.yunquan.ohana.base.binding.command.BindingConsumer
import com.yunquan.ohana.base.bus.RxBus
import com.yunquan.ohana.base.bus.RxSubscriptions
import com.yunquan.ohana.base.ui.BaseViewModel
import com.yunquan.ohana.db.DBFrames
import com.yunquan.ohana.entity.EventEntity
import com.yunquan.ohana.entity.EventType
import com.yunquan.ohana.entity.FramesDataManager
import com.yunquan.ohana.entity.FramesEntity
import com.yunquan.ohana.entity.LocalFrameEntity
import com.yunquan.ohana.entity.PushDataEntity
import com.yunquan.ohana.http.BaseHttp
import com.yunquan.ohana.http.observer.BaseObserver
import com.yunquan.ohana.http.transformer.CommonTransformer
import com.yunquan.ohana.ui.weather.WeatherActivity
import com.yunquan.ohana.utils.L
import com.yunquan.ohana.utils.SPUtils
import com.yunquan.ohana.utils.StringUtils
import com.yunquan.ohana.utils.ToastUtils
import com.yunquan.ohana.utils.Utils
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.disposables.Disposable
import okhttp3.RequestBody.Companion.toRequestBody

class HomeViewModel(application: Application) : BaseViewModel(application) {

    val isHave = ObservableField(false)

    val code = ObservableField<String>()
    val showError = ObservableField(false)
    val errorInfo = ObservableField<String>()

    val onInputChangeClick = BindingCommand(object : BindingConsumer<String> {
        override fun call(t: String) {
            if (showError.get() == true && t.isNotEmpty()) {
                showError.set(false)
            }
            if (t.length == 6) {
                L.e("验证码：${t}")
                bindFrames(t)
            }
        }
    })

    val onWeatherClick = BindingCommand<Any>(object : BindingAction{
        override fun call() {
            startActivity(WeatherActivity::class.java)
        }
    })

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        val token = SPUtils.getString("token")
        if (!StringUtils.isEmpty(token)) {
            isHave.set(true)
            showError.set(false)
            getFrames()
        } else {
            isHave.set(false)
        }
    }

    override fun onEvent(event: EventEntity) {
        super.onEvent(event)
        when (event.type) {
            EventType.GET_FRAMES -> {
                getFrames()
            }

            EventType.UPDATE_EMAIL -> {
                // 更换邮箱后重新拉取数据
                getFrames()
            }

            EventType.AUTH_FAILED -> {
                // 退出登录，清除相框
                FramesDataManager.instance.clear()
                isHave.set(false)
            }

            EventType.UPDATE_FRAMES_ONLINE -> {
                // 相框在线状态更新
                val bean = event.data as PushDataEntity?
                if (bean != null) {
                    val index = FramesDataManager.instance.getData().indexOfFirst { it.id == bean.id }
                    if (index >= 0) {
                        FramesDataManager.instance.getData()[index].online = bean.online
                        val temp = FramesDataManager.instance.getData()[index]
                        val entity = LocalFrameEntity(
                            deviceId = temp.id,
                            name = temp.name,
                            location = temp.roomLocation,
                            online = if (temp.online!!) 1 else 0
                        )
                        DBFrames.instance.saveOrUpdate(entity)
                        val list = FramesDataManager.instance.getData()
                        FramesDataManager.instance.setData(list)
                        RxBus.getDefault().post(EventEntity(EventType.FRESH_DEVICE_LIST))
                    }
                }
            }

            EventType.UPDATE_FRAMES_INFO -> {
                // 相框端信息更新
                val bean = event.data as PushDataEntity?
                if (bean != null) {
                    val index = FramesDataManager.instance.getData().indexOfFirst { it.id == bean.id }
                    if (index >= 0) {
                        FramesDataManager.instance.getData()[index].name = bean.name
                        FramesDataManager.instance.getData()[index].roomLocation = bean.roomLocation
                        val temp = FramesDataManager.instance.getData()[index]
                        val entity = LocalFrameEntity(
                            deviceId = temp.id,
                            name = temp.name,
                            location = temp.roomLocation,
                            online = if (temp.online!!) 1 else 0
                        )
                        DBFrames.instance.saveOrUpdate(entity)
                        RxBus.getDefault().post(EventEntity(EventType.FRESH_DEVICE_LIST))
                    }
                }
            }

            EventType.UNBIND_FRAMES -> {
                // 相框端解绑
                val bean = event.data as PushDataEntity?
                if (bean?.id != null) {
                    FramesDataManager.instance.removerAt(bean.id)
                    isHave.set(FramesDataManager.instance.getData().isEmpty())
                    if (isHave.get() == true) {
                        showError.set(false)
                    }
                    RxBus.getDefault().post(EventEntity(EventType.FRESH_DEVICE_LIST))
                }
            }

            EventType.BIND_FRAMES -> {
                // 相框端绑定发送变化
                getFrames()
            }

            else -> {}
        }
    }

    fun bindFrames(code: String) {
        val map = mutableMapOf<String, Any>()
        map["qrcode"] = code
        val json = Gson().toJson(map)
        val body = json.toRequestBody(BaseHttp.MEDIA_TYPE_JSON)
        BaseHttp.api.bindDevice(body)
            .compose(CommonTransformer())
            .subscribe(object : BaseObserver<Boolean>() {
                override fun onSuccess(result: Boolean?) {
                    super.onSuccess(result)
                    if (result == true) {
                        ToastUtils.showShort(R.string.bind_success)
                        getFrames()
                    } else {
                        if (isHave.get() == false) {
                            showError.set(true)
                            errorInfo.set(Utils.instance.getString(R.string.bind_failed))
                        } else {
                            ToastUtils.showShort(R.string.bind_failed)
                        }
                    }
                }
            })
    }

    fun getFrames() {
        val map = mutableMapOf<String, Any>()
        val json = Gson().toJson(map)
        val body = json.toRequestBody(BaseHttp.MEDIA_TYPE_JSON)
        BaseHttp.api.getUserDeviceList(body)
            .compose(CommonTransformer())
            .subscribe(object : BaseObserver<List<FramesEntity>>() {
                override fun onSuccess(result: List<FramesEntity>?) {
                    super.onSuccess(result)
                    if (result?.isNotEmpty() == true) {
                        isHave.set(true)
                        showError.set(false)
                    } else {
                        isHave.set(false)
                    }
                    result?.let {
                        FramesDataManager.instance.setData(it)
                        Thread {
                            for (e in it) {
                                val bean = LocalFrameEntity(
                                    deviceId = e.id,
                                    name = e.name,
                                    location = e.roomLocation,
                                    online = if (e.online!!) 1 else 0
                                )
                                DBFrames.instance.saveOrUpdate(bean)
                            }
                        }.start()
                        RxBus.getDefault().post(EventEntity(EventType.FRESH_DEVICE_LIST))
                    }
                }

                override fun onComplete() {
                    super.onComplete()
                    RxBus.getDefault().post(EventEntity(EventType.UPDATE_DEVICE_LIST_COMPLETE))
                }
            })
    }
}